#include "uifundlist.h"
#include "ui_uifundlist.h"

#include <QDebug>
#include <QLabel>
#include <QProgressBar>
#include <QPushButton>
#include <QVBoxLayout>
#include <QLineEdit>
#include <QMessageBox>

struct __queueFundListData_t{
    QListWidgetItem *item;
    QLabel *nameLabel;
    FundData *fundData;
    QString fund_code;
    QString fund_name;
};

static const QString notifyInputNewFundCodeQString = "Input new fund code:";
static const QString addButtonQString = "Add";
static const QString deleteButtonQString = "Delete";
static const QString warningQString = "Warning";
static const QString illegalCodeQString = "Illegal code";
static const QString addFailedQString = "Add failed, check the code and try it later";
static const QString noSuchFundQString = "No such fund, check the code and try it later";
static const QString alreadyExitQString = "Fund already exit, check the code and try it later";
///////////////////////////////////////////////////////////////////////
/*
    Tail line for adding new code
*/
void UIFundList::initTailLine() {
    QWidget *widget = new QWidget();
    QHBoxLayout *layout = new QHBoxLayout();

    QLabel *notifyLabel = new QLabel(notifyInputNewFundCodeQString);
    QLineEdit *codeEditer = new QLineEdit();
    codeEditer->setObjectName("codeEditer");
    QPushButton *addButton = new QPushButton(addButtonQString);
    connect(addButton, SIGNAL(clicked()), this, SLOT(buttonAddSingleItem()));
    connect(codeEditer, SIGNAL(returnPressed()), this, SLOT(buttonAddSingleItem()));
    layout->setContentsMargins(0, 0, 0, 0);

    layout->addWidget(notifyLabel);
    layout->addWidget(codeEditer);
    layout->addWidget(addButton);

    widget->setLayout(layout);

    taiLineItem = new QListWidgetItem();
    ui->listWidget->addItem(taiLineItem);
    ui->listWidget->setItemWidget(taiLineItem, widget);
}

void UIFundList::deleteTailLine() {
    QWidget *widget = ui->listWidget->itemWidget(taiLineItem);
    QHBoxLayout *layout = (QHBoxLayout *)widget->layout();
    QLayoutItem *litem = nullptr;
    while((litem = layout->itemAt(0)) != nullptr) {
        layout->removeItem(litem);
        delete litem->widget();
        delete litem;
    }

    delete layout;
    delete widget;
    ui->listWidget->removeItemWidget(taiLineItem);
    delete taiLineItem;
}

/*
    Add a code line
*/
bool UIFundList::addNewLine(QString code, QString name) {
    queueFundListData_t newFundListData;
    newFundListData.fund_code = code;
    newFundListData.fund_name = name;
    newFundListData.item = new QListWidgetItem();
    newFundListData.fundData = new FundData();

    QWidget *widget = new QWidget();
//    widget->setObjectName(code);
    QHBoxLayout *layout = new QHBoxLayout();
    QLabel *codeLabel = new QLabel(code);
//    QLabel *nameLabel = new QLabel(name);
//    nameLabel->setAlignment(Qt::AlignLeft);
    newFundListData.nameLabel = new QLabel(name);
    newFundListData.nameLabel->setAlignment(Qt::AlignLeft);
    QPushButton *deleteButton = new QPushButton(deleteButtonQString);
    deleteButton->setObjectName(code);
    connect(deleteButton, SIGNAL(clicked()), this, SLOT(buttonDeleteSingleItem()));

    layout->setContentsMargins(0, 0, 0, 0);
    layout->addWidget(codeLabel);
    layout->addWidget(newFundListData.nameLabel);
    layout->addWidget(deleteButton);

    widget->setLayout(layout);
    ui->listWidget->insertItem(ui->listWidget->count() - 1, newFundListData.item);
    ui->listWidget->setItemWidget(newFundListData.item, widget);

    fundDataList->append(newFundListData);

    if(code.compare(name) == 0) {
        // ASyn ask
        QObject::connect(newFundListData.fundData, SIGNAL(singleFinished(QString, bool)), this, SLOT(gottenSingleData(QString, bool)));
        newFundListData.fundData->askSingle(code);
    }

    return true;
}

void UIFundList::gottenSingleData(QString code, bool rslt) {
    for(int i = 0; i < fundDataList->size(); i ++) {
        if(fundDataList->at(i).fund_code.compare(code) == 0) {
            if(rslt) {
                FundData *fundData = fundDataList->at(i).fundData;
//                qDebug() << fundData->getSingle().stringData;
                if(fundData->getSingle().stringData != "NULL") {
                    int rslt = sqlList->insert_by_code_and_name(fundData->getSingle().code, fundData->getSingle().name);
                    if(rslt == 0) {
                        // Disconnect and delete spider
                        fundDataList->at(i).nameLabel->setText(fundData->getSingle().name);
                        fundData->deleteLater();
                        emit addFund(fundData->getSingle().code, fundData->getSingle().stringData);
                    } else {
                        deleteLine(code);
                        qDebug() << "Add failed, check the code and try it later" << endl;
                        QMessageBox::information(NULL, warningQString, addFailedQString, QMessageBox::Ok);
                    }
                }
            } else {
                deleteLine(code);
                qDebug() << "No such fund, check the code and try it later" << endl;
                QMessageBox::information(NULL, "Warning", noSuchFundQString, QMessageBox::Ok);
            }
            break;
        }
    } // End while
}

/*
    Delete a code line
*/
void UIFundList::deleteLine(QString code) {
    for(int i = 0; i < fundDataList->size(); i++) {
        if(fundDataList->at(i).fund_code.compare(code) == 0) {
            if(fundDataList->at(i).nameLabel->text().compare(code) == 0) {
                // Not found name means is an unvalid code
                // A valid code delete spider before
                qDebug() << "delete fundData";
                fundDataList->at(i).fundData->deleteLater();
            }
            // Delete ui
            QWidget *widget = ui->listWidget->itemWidget(fundDataList->at(i).item);
            QHBoxLayout *layout = (QHBoxLayout *)widget->layout();
            QLayoutItem *litem = nullptr;
            while((litem = layout->itemAt(0)) != nullptr) {
                layout->removeItem(litem);
                delete litem->widget();
                delete litem;
            }

            delete layout;
            delete widget;
            ui->listWidget->removeItemWidget(fundDataList->at(i).item);
            delete fundDataList->at(i).item;

            fundDataList->removeAt(i);
            sqlList->delete_by_code(code);
            emit deleteFund(code);
            break;
        }
    }
}

void UIFundList::initAllItem() {
    initTailLine();
    int listCount = size();
    for(int i = 0; i < listCount; i++) {
        addNewLine(getCode(i) == NULL ? "NULL" : getCode(i), getName(i) == NULL ? "NULL" : getName(i));
    }
}

void UIFundList::deleteAllItem() {
    deleteTailLine();
    for(int i = 0; i < fundDataList->size(); i++) {
        deleteLine(fundDataList->at(i).fund_code);
    }
}

///////////////////////////////////////////////////////////////////////
UIFundList::UIFundList(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::UIFundList)
{
    ui->setupUi(this);
    relocate();
    sqlList = new SQL_FundList();
//    fundData = new FundData();
    fundDataList = new QList<queueFundListData_t>;
    ui->listWidget->setContentsMargins(0, 0, 0, 0);

    initAllItem();
}

UIFundList::~UIFundList() {
    delete sqlList;
//    deleteAllItem();
    fundDataList->clear();
    delete fundDataList;
    delete ui;
}

void UIFundList::buttonDeleteSingleItem() {
    deleteLine(sender()->objectName());
}

void UIFundList::buttonAddSingleItem() {
    QWidget *widget = (QWidget *)(sender()->parent());
    QLineEdit *codeEditor = widget->findChild<QLineEdit*>("codeEditer");
//    qDebug() << "add new fund " << sender()->parent() << " " << codeEditor << endl;
    if(codeEditor != NULL) {
        if(codeEditor->text().length() == 6) {
            sqlList->checkCode(codeEditor->text());
            if(!sqlList->checkCode(codeEditor->text())) {
                if(addNewLine(codeEditor->text(), codeEditor->text())) {
                    // Clear codeEditor and scroll to the end
                    codeEditor->setText("");
                    ui->listWidget->scrollToBottom();
                }
            } else {
                qDebug() << alreadyExitQString;
                QMessageBox::information(NULL, warningQString, alreadyExitQString, QMessageBox::Ok);
            }
        } else {
            qDebug() << "Illegal code" << endl;
            QMessageBox::information(NULL, warningQString, illegalCodeQString, QMessageBox::Ok);
        }
    } else {
        qDebug() << "codeEditor null" << endl;
    }
}

int UIFundList::size() {
//    qDebug() << "fund list count is " << sqlList->get_fundList_count() << endl;
    return sqlList->get_fundList_count();
}

QString UIFundList::getCode(int index) {
    int sqlSize = sqlList->get_fundList_count();
    if(index > sqlSize) {
        return NULL;
    } else {
        sql_fundListData data = sqlList->get_fundList_by_index(index);
        return data.code;
    }
}

QString UIFundList::getName(int index) {
    int sqlSize = sqlList->get_fundList_count();
    if(index > sqlSize) {
        return NULL;
    } else {
        sql_fundListData data = sqlList->get_fundList_by_index(index);
        return data.name;
    }
}

void UIFundList::resizeEvent(QResizeEvent *event) {
    resize();
}

void UIFundList::relocate() {
    ui->listWidget->setGeometry(geometry().x() + 10, geometry().y() + 10, width() - 20, height() - 20);
}
void UIFundList::resize() {
    ui->listWidget->resize(width() - 20, height() - 20);
}
